/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package InstanciaJogo.FasesJogo;

import ClassesListas.Imagens;
import ClassesListas.ImagensApresentadasSubFase;
import DAO.DAOInstanciaSubFase;
import DAO.MySQL.DAOInstanciaSubFaseMySQL;
import InstanciaJogo.InstanciaJogoSwing;
import java.util.Timer;

/**
 * InstanciaSubFasePattern
 *
 * Versao 1.0
 *
 * Data Criação 04/04/2014
 *
 * @author Igor
 */
public abstract class InstanciaSubFasePattern {
    //Atributos
    protected long idInstanciaSubFase;
    private long idFase;
    protected long subFase;
    protected long subFaseUltima; //Ultima subFase da Fase
    protected ImagensApresentadasSubFase imagensDinamicas;
    protected int indiceImagensSubFase; //Indice do grupo de imagens dinamicas
    protected int indiceImagemApresentada; //Indice da imagem apresentada no JLabel
    protected int quantidadeImagensParaAvaliar;
    protected Timer timerApresentarImagem;
    protected int quantidadeImagensAvaliadasCorretamente;
    protected long tempoParaAvaliar;
    protected long tempoInicioSubFase;
    private int percAvancarSubFases;

    //DAO
    protected DAOInstanciaSubFase subFaseDAO;

    //Construtor
    public InstanciaSubFasePattern(long subFase) {
        this.imagensDinamicas = new ImagensApresentadasSubFase();
        this.subFase = subFase;
        this.indiceImagemApresentada = 0;
        this.indiceImagensSubFase = 0;
        this.quantidadeImagensParaAvaliar = 0;
        this.subFaseDAO = new DAOInstanciaSubFaseMySQL();
        this.quantidadeImagensAvaliadasCorretamente = 0;
        this.tempoInicioSubFase = System.currentTimeMillis();
    }

    /**
     * @return the idInstanciaSubFase
     */
    public long getIdInstanciaSubFase() {
        return idInstanciaSubFase;
    }

    /**
     * @param idInstanciaSubFase the idInstanciaSubFase to set
     */
    public void setIdInstanciaSubFase(long idInstanciaSubFase) {
        this.idInstanciaSubFase = idInstanciaSubFase;
    }

    /**
     * @return the idFase
     */
    public long getIdFase() {
        return idFase;
    }

    /**
     * @param idFase the idFase to set
     */
    public void setIdFase(long idFase) {
        this.idFase = idFase;
    }

    /**
     * @return the subFase
     */
    public long getSubFase() {
        return subFase;
    }

    /**
     * @param subFase the subFase to set
     */
    public void setSubFase(long subFase) {
        this.subFase = subFase;
    }

    /**
     * @return the subFaseUltima
     */
    public long getSubFaseUltima() {
        return subFaseUltima;
    }

    /**
     * @param subFaseUltima the subFaseUltima to set
     */
    public void setSubFaseUltima(long subFaseUltima) {
        this.subFaseUltima = subFaseUltima;
    }

    /**
     * @return the imagensDinamicas
     */
    public ImagensApresentadasSubFase getImagensDinamicas() {
        return imagensDinamicas;
    }

    /**
     * @param imagensDinamica the imagensDinamicas to set
     */
    public void setImagensDinamicas(ImagensApresentadasSubFase imagensDinamica) {
        this.imagensDinamicas = imagensDinamica;
    }

    /**
     * @return the indiceImagensSubFase
     */
    public int getIndiceImagensSubFase() {
        return indiceImagensSubFase;
    }

    /**
     * @param indiceImagensDinamica the indiceImagensSubFase to set
     */
    public void setIndiceImagensSubFase(int indiceImagensDinamica) {
        this.indiceImagensSubFase = indiceImagensDinamica;
    }

    /**
     * @return the indiceImagemApresentada
     */
    public int getIndiceImagemApresentada() {
        return indiceImagemApresentada;
    }

    /**
     * @param indiceImagemApresentada the indiceImagemApresentada to set
     */
    public void setIndiceImagemApresentada(int indiceImagemApresentada) {
        this.indiceImagemApresentada = indiceImagemApresentada;
    }

    /**
     * @return the quantidadeImagensParaAvaliar
     */
    public int getQuantidadeImagensParaAvaliar() {
        return quantidadeImagensParaAvaliar;
    }

    /**
     * @param quantidadeImagensParaAvaliar the quantidadeImagensParaAvaliar to
     * set
     */
    public void setQuantidadeImagensParaAvaliar(int quantidadeImagensParaAvaliar) {
        this.quantidadeImagensParaAvaliar = quantidadeImagensParaAvaliar;
    }

    /**
     * Insere quantidade de imagens para avaliar baseado na quantidade de
     * imagens
     */
    public void setQuantidadeImagensParaAvaliar() {
        this.quantidadeImagensParaAvaliar = getImagensDinamicas().getImagensApresentadasSubFase().size();//getImagensFase().getImagens().size();
    }

    /**
     * @return the timerApresentarImagem
     */
    public Timer getTimerApresentarImagem() {
        return timerApresentarImagem;
    }

    /**
     * @param timerApresentarImagem the timerApresentarImagem to set
     */
    public void setTimerApresentarImagem(Timer timerApresentarImagem) {
        this.timerApresentarImagem = timerApresentarImagem;
    }

    /**
     * @return the quantidadeImagensAvaliadasCorretamente
     */
    public int getQuantidadeImagensAvaliadasCorretamente() {
        return quantidadeImagensAvaliadasCorretamente;
    }

    /**
     * @param quantidadeImagensAvaliadasCorretamente the
     * quantidadeImagensAvaliadasCorretamente to set
     */
    public void setQuantidadeImagensAvaliadasCorretamente(int quantidadeImagensAvaliadasCorretamente) {
        this.quantidadeImagensAvaliadasCorretamente = quantidadeImagensAvaliadasCorretamente;
    }

    /**
     * @return the tempoParaAvaliar
     */
    public long getTempoParaAvaliar() {
        return tempoParaAvaliar;
    }

    /**
     * @param tempoParaAvaliar the tempoParaAvaliar to set
     */
    public void setTempoParaAvaliar(long tempoParaAvaliar) {
        this.tempoParaAvaliar = tempoParaAvaliar;
    }

    /**
     * @return the tempoInicioSubFase
     */
    public long getTempoInicioSubFase() {
        return tempoInicioSubFase;
    }

    /**
     * @param tempoInicioSubFase the tempoInicioSubFase to set
     */
    public void setTempoInicioSubFase(long tempoInicioSubFase) {
        this.tempoInicioSubFase = tempoInicioSubFase;
    }

    /**
     * @return the percAvancarSubFases
     */
    public int getPercAvancarSubFases() {
        return percAvancarSubFases;
    }

    /**
     * @param percAvancarSubFases the percAvancarSubFases to set
     */
    public void setPercAvancarSubFases(int percAvancarSubFases) {
        this.percAvancarSubFases = percAvancarSubFases;
    }

    /**
     * @return the subFaseDAO
     */
    public DAOInstanciaSubFase getSubFaseDAO() {
        return subFaseDAO;
    }

    /**
     * @param subFaseDAO the subFaseDAO to set
     */
    public void setSubFaseDAO(DAOInstanciaSubFase subFaseDAO) {
        this.subFaseDAO = subFaseDAO;
    }

    //Outros metodos
    /**
     * Realiza a gravaçao da sub fase no BD
     *
     * @param idJogo
     * @return
     */
    public long gravaInstanciaSubFase(long idJogo) throws Exception {
        return this.getSubFaseDAO().gravaInstanciaSubFase(idJogo, getIdFase(), getSubFase());
    }

    /**
     * Retorna a porcentagem de imagens avaliadas corretamente daquela subfase
     * específica
     *
     * @return
     */
    public long buscaPorcentagemAcerto() {
        if(getImagensDinamicas().getImagensApresentadasSubFase().size() > 0){
            return (this.quantidadeImagensAvaliadasCorretamente * 100 / getImagensDinamicas().getImagensApresentadasSubFase().size());
        }
        return 0;
    }

    /**
     * Metodo que retorna a ultima imagem apresentada
     *
     * @return O objeto imagem, que foi apresentado por ultimo
     */
    public Imagens imagemApresentadaAtual() {
        return getImagensDinamicas().getImagensApresentadasSubFase().get(getIndiceImagensSubFase()- 1);
    }

    /**
     * Retorna a proxima imagem a ser apresentada
     *
     * @return a proxima imagem a ser apresentada
     */
    public Imagens retornaProximaImagemApresentada() {
        Imagens imagemRetorno = null;

        if (this.getQuantidadeImagensParaAvaliar() > 0) {
            imagemRetorno = selecionaProximaImagemApresentada();

            //Enquanto a imagem nao for uma imagem ja avaliada, pois ele repete ate que se avalie tds as expressoes
            while (imagemRetorno.getImagens().get(0).getIdExpressaoResposta() != null
                    && getQuantidadeImagensParaAvaliar() > 0) {
                imagemRetorno = selecionaProximaImagemApresentada();
            }
        }
        return imagemRetorno;
    }

    /**
     * Faz a selecao da imagem a ser apresentada, excluindo as ja avaliadas ou
     * que foram apresentadas acima do limite
     *
     * @return
     */
    public Imagens selecionaProximaImagemApresentada() {
        Imagens imagemRetorno;
        if (getQuantidadeImagensParaAvaliar() > 0
                && getIndiceImagensSubFase() >= getImagensDinamicas().getImagensApresentadasSubFase().size()) {
            setIndiceImagensSubFase((int) (0));
        }

        imagemRetorno = getImagensDinamicas().getImagensApresentadasSubFase().get(getIndiceImagensSubFase());
        setIndiceImagensSubFase((int) (getIndiceImagensSubFase() + 1));

        return imagemRetorno;
    }

    /**
     * Mostra a imagem no JLabel de apresentacao e escreve informacoes sobre a
     * imagem apresentada
     *
     * @param instanciaJogo
     * @param jogoPausado define se a apresentacao da imagem prove do pause no
     * jogo
     */
    public void apresentarImagem(InstanciaJogoSwing instanciaJogo, boolean jogoPausado) throws Exception {
    }

    /**
     * Avalia a imagem apresentada
     *
     * @param idExpressao expressao avaliada pelo jogador
     * @return Verdadeiro ou Falso de acordo com a comparacao da expressao
     */
    public boolean avaliarExpressaoImagem(int idExpressao, long idModoJogo) throws Exception {
        return false;
    }
    
    /**
     * Para o timer de apresentacao das imagens
     */
    public void stopTimer() {
        if (getTimerApresentarImagem() != null) { 
           getTimerApresentarImagem().cancel();
            getTimerApresentarImagem().purge();
        }
        setTimerApresentarImagem(null);
    }
}
